<?php

namespace app\common;

use think\facade\Db;
use think\Model;

abstract class BaseModel extends Model
{

  private static $instances = [];

  public static function getInstance() {
    if (!isset(self::$instances[static::class])) {
      self::$instances[static::class] = new static();
    }
    return self::$instances[static::class];
  }

  public function list(
    $conditions = [],
    $page = 0,
    $pageSize = 10,
    $orderField = 'id',
    $orderSort = 'DESC'
  ) {
    $result = self::getDataList($conditions, $page, $pageSize, $orderField, $orderSort, false);
    return !empty($result) ? $result : [];
  }

  protected function getDataList(
    $conditions = [],
    $page = 0,
    $pageSize = 10,
    $orderField = 'id',
    $orderSort = 'DESC',
    $count = false
  ) {
    $query = $this;
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $query = $query->where($field, $op, $value);
    }
    if ($orderField != 'id') {
      $orderStr = $orderField.' '.$orderSort.',id';
      $query = $query->order($orderStr, 'ASC');
    } else {
      $query = $query->order($orderField, $orderSort);
    }
    if ($page > 0) {
      list($offset, $limit) = $this->offsetConverter($page, $pageSize);
      $query = $query->limit($offset, $limit);
    }
    if ($count) {
      return $query->count();
    }
    else {
      return $query->select()->toArray();
    }
    return $result;
  }

  public function pager(
    $conditions = [],
    $page = 0,
    $pageSize = 10,
    $order = []
  ) {
    $totalCount = $this->getDataDetail(
      $conditions,
      $page,
      $pageSize,
      $order,
      true
    );
    return [
      'totalCount' => intval($totalCount),
      'pageSize' => intval($pageSize),
      'currPage' => intval($page),
      'totalPage' => ceil($totalCount / $pageSize),
    ];
  }

  public function getDataDetail(
    $conditions = [],
    $page = 0,
    $pageSize = 10,
    $order = ['id' => 'desc'],
    $count = false
  ) {
    $result = $this;
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $result = $result->where($field, $op, $value);
    }
    if ($order) {
      $result = $result->order($order);
    }
    if ($page > 0 && $count == false) {
      list($offset, $limit) = $this->offsetConverter($page, $pageSize);
      $result = $result->limit($offset, $limit);
    }

    if ($count) {
      return $result->count();
    }
    else {
      return $result->select()->toArray();
    }
  }


  public function offsetConverter($page, $pageSize = 10) {
    if ($page < 1) {
      $page = 1;
    }
    $offset = ($page - 1) * $pageSize;
    return [$offset, $pageSize];
  }

  /**
   * 通过条件获取数据集
   *
   * @param array $conditions 例如 [ ['id', 1, '='], ['status', 1, '='] ]
   * @return mixed
   */
  public function getDataByCondition($conditions = [], $order = ['id' => 'desc'])
  {
    $db = $this;
    foreach ($conditions as $item) {
      list($field, $value, $condition ) = $item;
      if (!$condition) {
        $condition = '=';
      }
      $db = $db->where($field, $condition, $value);
    }
    $db = $db->order($order)->select();
    return $db->toArray();
  }


}